#include <iostream>
#include <vector>
#include <list>
#include <map>
#include <assert.h>
#include <algorithm>
#include <functional>
using namespace std;

//class Date
//{
//public:
//	Date(int year, int month, int day)
//		:_year(year)
//		, _month(month)
//		, _day(day)
//	{
//		cout << "Date(int year, int month, int day)" << endl;
//	}
//
//protected:
//	int _year = 1;
//	int _month = 1;
//	int _day = 1;
//};

//int main()
//{
//	int x1 = 1;
//
//	int x2 = { 2 }; // 不建议使用
//	int x3{ 2 };
//
//	Date d1(2023, 1, 1); // 都是在调用构造函数
//
//	Date d2 = { 2023, 2, 2 }; // 不建议使用
//	Date d3{ 2023, 3, 3 };
//
//	// 调用支持list (initializer_list<value_type> il）类似这样的构造函数
//	vector<int> v1 = { 1, 2, 3, 4, 5, 6 };
//	vector<int> v2 { 1, 2, 3, 4, 5, 6 };
//
//	list<int> lt1 = { 1, 2, 3, 4, 5, 6 };
//	list<int> lt2{ 1, 2, 3, 4, 5, 6 };
//
//	auto x = { 1, 2, 3, 4, 5, 6 };
//	cout << typeid(x).name() << endl; // 打印初始化列表的类型
//
//	vector<Date> v3 = {d1, d2, d3};
//	vector<Date> v4 = { { 2022, 1, 1 }, {2022, 11, 11} };
//
//	string s1 = "11111";
//
//	map<string, string> dict = { { "sort", "排序" }, { "insert", "插入" } }; // 构造
//
//	initializer_list<pair<const string, string>> kvil = { { "left", "左边" }, { "right", "右边" } }; // 赋值重载
//	dict = kvil; // 上面的类型就不能用auto推导，编译器不知道那里是一个pair
//
//	return 0;
//}

//template<class T1, class T2>
//void F(T1 t1, T2 t2)
//{
//	decltype(t1 * t2) ret;
//	cout << typeid(ret).name() << endl;
//}
//
//int main()
//{
//	const int x = 1;
//	double y = 2.2;
//	decltype(x * y) ret; // ret的类型是double
//	decltype(&x) p; // p的类型是int*
//	cout << typeid(ret).name() << endl;
//	cout << typeid(p).name() << endl;
//	F(1, 2);
//	return 0;
//}

//// x既能接收左值，也能接收右值
//template<class T>
//void Func(const T& x)
//{}
//
//int main()
//{
//	// 有条件的支持
//	// 左值引用可以引用右值吗？ const的左值引用可以
//	double x = 1.1, y = 2.2;
//	//double& r1 = x + y;
//	const double& r1 = x + y;
//
//	// 右值引用可以引用左值吗？可以引用move以后的左值
//	int b = 7;
//	//int&& rr5 = b;
//	int&& rr5 = move(b);
//
//	return 0;
//}

//int main()
//{
//	double x = 1.1, y = 2.2;
//	int&& rr1 = 10;
//	const double&& rr2 = x + y;
//
//	rr1 = 20;
//	//rr2 = 5.5;  // 报错
//
//	cout << &rr1 << endl;
//	cout << &rr2 << endl;
//
//
//	return 0;
//}

//namespace rtx
//{
//	class string
//	{
//	public:
//		string(const char* str = "")
//			:_size(strlen(str))
//			, _capacity(_size)
//		{
//			_str = new char[_capacity + 1];
//			strcpy(_str, str);
//		}
//
//		void swap(string& s)
//		{
//			::swap(_str, s._str);
//			::swap(_size, s._size);
//			::swap(_capacity, s._capacity);
//		}
//
//		string(const string& s) // 拷贝构造
//			:_str(nullptr)
//			, _size(0)
//			, _capacity(0)
//		{
//			cout << "string(const string& s) -- 拷贝构造(深拷贝)" << endl;
//			string tmp(s._str);
//			swap(tmp);
//		}	
//
//		string(string&& s) // 移动构造
//			:_str(nullptr)
//			, _size(0)
//			, _capacity(0)
//		{
//			cout << "string(string&& s) -- 移动构造(资源转移)" << endl;
//			swap(s);
//		}
//
//		string& operator=(const string& s) // 拷贝赋值
//		{
//			cout << "string& operator=(string s) -- 拷贝赋值(深拷贝)" << endl;
//			string tmp(s);
//			swap(tmp);
//
//			return *this;
//		}
//
//		string& operator=(string&& s) // 移动赋值
//		{
//			cout << "string& operator=(string s) -- 移动赋值(资源移动)" << endl;
//			swap(s);
//
//			return *this;
//		}
//
//		~string()
//		{
//			delete[] _str;
//			_str = nullptr;
//		}
//
//		void reserve(size_t n)
//		{
//			if (n > _capacity)
//			{
//				char* tmp = new char[n + 1];
//				strcpy(tmp, _str);
//				delete[] _str;
//				_str = tmp;
//
//				_capacity = n;
//			}
//		}
//
//		void push_back(char ch)
//		{
//			if (_size >= _capacity)
//			{
//				size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2;
//				reserve(newcapacity);
//			}
//
//			_str[_size] = ch;
//			++_size;
//			_str[_size] = '\0';
//		}
//
//	protected:
//		char* _str;
//		size_t _size;
//		size_t _capacity;
//	};
//}
//
//int main()
//{
//	list<rtx::string> lt;
//	rtx::string s1("hello"); // 左值
//	lt.push_back(s1);  // 插入左值
//
//	cout << "----------------------------------" << endl;
//
//	lt.push_back(rtx::string("world")); // 插入右值
//	//lt.push_back("world");
//
//	return 0;
//}

//void Func(rtx::string& s)
//{}
//
//int main()
//{
//	rtx::string s("hello world");
//	Func(s);
//
//	return 0;
//}

//void Fun(int& x) { cout << "左值引用" << endl; }
//void Fun(const int& x) { cout << "const 左值引用" << endl; }
//
//void Fun(int&& x) { cout << "右值引用" << endl; }
//void Fun(const int&& x) { cout << "const 右值引用" << endl; }
//
//
//// 万能引用(引用折叠)：t既能引用左值，也能引用右值
//template<typename T>
//void PerfectForward(T&& t)
//{
//	Fun(std::forward<T>(t)); // 完美转发：保持t引用对象属性
//}
//
//int main()
//{
//	PerfectForward(10);           // 右值
//
//	int a;
//	PerfectForward(a);            // 左值
//	PerfectForward(std::move(a)); // 右值
//
//	const int b = 8;
//	PerfectForward(b);		      // const 左值
//	PerfectForward(std::move(b)); // const 右值
//
//	return 0;
//}

namespace rtx
{
	class string
	{
	public:
		string(const char* str = "")
			:_size(strlen(str))
			, _capacity(_size)
		{
			_str = new char[_capacity + 1];
			strcpy(_str, str);
		}

		void swap(string& s)
		{
			::swap(_str, s._str);
			::swap(_size, s._size);
			::swap(_capacity, s._capacity);
		}

		string(const string& s) // 拷贝构造
			:_str(nullptr)
			, _size(0)
			, _capacity(0)
		{
			cout << "string(const string& s) -- 拷贝构造(深拷贝)" << endl;
			string tmp(s._str);
			swap(tmp);
		}

		string(string&& s) // 移动构造
			:_str(nullptr)
			, _size(0)
			, _capacity(0)
		{
			cout << "string(string&& s) -- 移动构造(资源转移)" << endl;
			swap(s);
		}

		string& operator=(const string& s) // 拷贝赋值
		{
			cout << "string& operator=(string s) -- 拷贝赋值(深拷贝)" << endl;
			string tmp(s);
			swap(tmp);

			return *this;
		}

		string& operator=(string&& s) // 移动赋值
		{
			cout << "string& operator=(string s) -- 移动赋值(资源移动)" << endl;
			swap(s);

			return *this;
		}

		~string()
		{
			delete[] _str;
			_str = nullptr;
		}

	protected:
		char* _str;
		size_t _size;
		size_t _capacity;
	};
}

class Person
{
public:
	Person(const char* name = "", int age = 0)
		:_name(name)
		, _age(age)
	{}
	Person(const Person& p) // 拷贝构造
		:_name(p._name)
		, _age(p._age)
	{}
	Person& operator=(const Person& p) // 拷贝赋值
	{
		if (this != &p)
		{
			_name = p._name;
			_age = p._age;
		}
		return *this;
	}
	~Person()
	{}

	Person(Person&& p)
	{}

protected:
	rtx::string _name;
	int _age;
};

int main()
{
	Person s1;
	Person s2 = s1;
	Person s3 = std::move(s1);
	Person s4;
	s4 = std::move(s2);
	return 0;
}